#ifndef GUDB_BACKUP_SYSTEM_H
#define GUDB_BACKUP_SYSTEM_H

#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <pthread.h>
#include "../utils/logger.h"
#include "../../include/gudb.h"

#ifdef __cplusplus
extern "C" {
#endif

// Forward declarations
typedef struct backup_system backup_system_t;
typedef struct backup_manifest backup_manifest_t;
typedef struct backup_job backup_job_t;
typedef struct recovery_context recovery_context_t;

// Backup types
typedef enum {
    BACKUP_TYPE_FULL = 0,           // Complete database backup
    BACKUP_TYPE_INCREMENTAL = 1,    // Changes since last backup
    BACKUP_TYPE_DIFFERENTIAL = 2,   // Changes since last full backup
    BACKUP_TYPE_LOG = 3             // Transaction log backup
} backup_type_t;

// Backup status
typedef enum {
    BACKUP_STATUS_PENDING = 0,
    BACKUP_STATUS_RUNNING = 1,
    BACKUP_STATUS_COMPLETED = 2,
    BACKUP_STATUS_FAILED = 3,
    BACKUP_STATUS_CANCELLED = 4
} backup_status_t;

// Recovery types
typedef enum {
    RECOVERY_TYPE_FULL = 0,         // Complete database restore
    RECOVERY_TYPE_POINT_IN_TIME = 1,// Restore to specific point in time
    RECOVERY_TYPE_TRANSACTION = 2,  // Restore to specific transaction
    RECOVERY_TYPE_PAGE = 3          // Restore specific pages
} recovery_type_t;

// Compression algorithms
typedef enum {
    COMPRESSION_NONE = 0,
    COMPRESSION_GZIP = 1,
    COMPRESSION_LZ4 = 2,
    COMPRESSION_ZSTD = 3
} compression_type_t;

// Encryption algorithms
typedef enum {
    ENCRYPTION_NONE = 0,
    ENCRYPTION_AES128 = 1,
    ENCRYPTION_AES256 = 2
} encryption_type_t;

// Backup configuration
typedef struct {
    char backup_directory[512];     // Backup storage directory
    backup_type_t default_type;     // Default backup type
    compression_type_t compression; // Compression algorithm
    encryption_type_t encryption;   // Encryption algorithm
    uint32_t max_backup_threads;    // Maximum parallel backup threads
    uint64_t max_backup_size;       // Maximum backup size (bytes)
    uint32_t retention_days;        // How long to keep backups
    uint32_t max_backup_count;      // Maximum number of backups to keep
    bool enable_checksum;           // Enable backup integrity checking
    bool enable_compression;        // Enable compression
    bool enable_encryption;         // Enable encryption
    uint32_t backup_buffer_size;    // Buffer size for backup operations
    uint32_t network_timeout_sec;   // Network timeout for remote backups
} backup_config_t;

// File metadata for backup
typedef struct {
    char filename[256];             // File name
    char full_path[512];            // Full file path
    uint64_t file_size;             // File size in bytes
    uint64_t checksum;              // File checksum (CRC64)
    time_t modified_time;           // Last modification time
    uint32_t permissions;           // File permissions
    bool is_compressed;             // Whether file is compressed
    bool is_encrypted;              // Whether file is encrypted
} backup_file_info_t;

// Backup manifest - contains backup metadata
struct backup_manifest {
    uint64_t backup_id;             // Unique backup ID
    backup_type_t backup_type;      // Type of backup
    time_t backup_start_time;       // When backup started
    time_t backup_end_time;         // When backup completed
    uint64_t database_size;         // Size of database at backup time
    uint64_t backup_size;           // Size of backup files
    uint64_t compressed_size;       // Size after compression
    char database_version[32];      // Database version
    char backup_version[32];        // Backup format version
    uint64_t lsn_start;             // Starting LSN for backup
    uint64_t lsn_end;               // Ending LSN for backup
    uint32_t file_count;            // Number of files in backup
    backup_file_info_t* files;      // Array of file information
    char checksum[65];              // SHA256 checksum of manifest
    
    // Dependencies
    uint64_t base_backup_id;        // Base backup ID (for incremental)
    uint64_t* dependency_ids;       // Array of dependent backup IDs
    uint32_t dependency_count;      // Number of dependencies
    
    // Metadata
    char description[512];          // Backup description
    char created_by[64];            // User who created backup
    char hostname[64];              // Host where backup was created
    bool is_valid;                  // Whether backup is valid
    bool is_archived;               // Whether backup is archived
};

// Backup job - represents a backup operation
struct backup_job {
    uint64_t job_id;                // Unique job ID
    backup_type_t backup_type;      // Type of backup
    backup_status_t status;         // Current status
    time_t start_time;              // Job start time
    time_t end_time;                // Job end time
    uint64_t bytes_processed;       // Bytes processed so far
    uint64_t total_bytes;           // Total bytes to process
    uint32_t files_processed;       // Files processed
    uint32_t total_files;           // Total files to process
    double progress_percent;        // Progress percentage
    char error_message[512];        // Error message if failed
    char backup_path[512];          // Path to backup files
    
    // Threading
    pthread_t thread;               // Backup thread
    pthread_mutex_t mutex;          // Job mutex
    bool thread_active;             // Whether thread is active
    
    // Cancellation
    bool cancelled;                 // Whether job was cancelled
    bool can_cancel;                // Whether job can be cancelled
    
    // Linked list
    struct backup_job* next;        // Next job in list
    struct backup_job* prev;        // Previous job in list
};

// Recovery context - represents a recovery operation
struct recovery_context {
    uint64_t recovery_id;           // Unique recovery ID
    recovery_type_t recovery_type;  // Type of recovery
    uint64_t target_backup_id;      // Backup to recover from
    time_t target_time;             // Target time for point-in-time recovery
    uint64_t target_lsn;            // Target LSN for recovery
    char recovery_path[512];        // Path for recovery files
    
    // Progress tracking
    uint64_t bytes_processed;       // Bytes processed
    uint64_t total_bytes;           // Total bytes to process
    uint32_t files_processed;       // Files processed
    uint32_t total_files;           // Total files to process
    double progress_percent;        // Progress percentage
    
    // Status
    backup_status_t status;         // Recovery status
    time_t start_time;              // Recovery start time
    time_t end_time;                // Recovery end time
    char error_message[512];        // Error message if failed
    
    // Options
    bool force_overwrite;           // Force overwrite existing files
    bool verify_checksums;          // Verify file checksums
    bool restore_permissions;       // Restore file permissions
};

// Backup system statistics
typedef struct {
    uint64_t total_backups;         // Total number of backups
    uint64_t successful_backups;    // Number of successful backups
    uint64_t failed_backups;        // Number of failed backups
    uint64_t total_backup_size;     // Total size of all backups
    uint64_t compressed_size;       // Total compressed size
    double compression_ratio;       // Average compression ratio
    uint64_t total_recoveries;      // Total number of recoveries
    uint64_t successful_recoveries; // Number of successful recoveries
    uint64_t failed_recoveries;     // Number of failed recoveries
    time_t last_backup_time;        // Time of last backup
    time_t last_recovery_time;      // Time of last recovery
    uint32_t active_jobs;           // Number of active backup jobs
    double avg_backup_time_sec;     // Average backup time
    double avg_recovery_time_sec;   // Average recovery time
} backup_system_stats_t;

// Main backup system
struct backup_system {
    // Configuration
    backup_config_t config;         // System configuration
    backup_system_stats_t stats;    // System statistics
    gudb* database;                 // Database handle
    logger_t* logger;               // Logger instance
    
    // Backup storage
    backup_manifest_t** manifests;  // Array of backup manifests
    uint32_t manifest_count;        // Number of manifests
    uint32_t max_manifests;         // Maximum number of manifests
    uint64_t next_backup_id;        // Next backup ID
    
    // Job management
    backup_job_t* active_jobs;      // List of active jobs
    backup_job_t* completed_jobs;   // List of completed jobs
    uint32_t active_job_count;      // Number of active jobs
    uint32_t completed_job_count;   // Number of completed jobs
    uint64_t next_job_id;           // Next job ID
    
    // Recovery management
    recovery_context_t* active_recoveries; // Active recovery operations
    uint32_t active_recovery_count; // Number of active recoveries
    uint64_t next_recovery_id;      // Next recovery ID
    
    // Thread management
    pthread_t scheduler_thread;     // Backup scheduler thread
    pthread_t cleanup_thread;       // Cleanup thread
    bool threads_running;           // Whether threads are running
    
    // Synchronization
    pthread_rwlock_t manifests_lock;// Manifests read-write lock
    pthread_mutex_t jobs_mutex;     // Jobs mutex
    pthread_mutex_t stats_mutex;    // Statistics mutex
    pthread_cond_t job_cond;        // Job condition variable
    
    // System state
    bool initialized;               // System initialization status
    bool shutting_down;             // Whether system is shutting down
    time_t start_time;              // When system was started
};

// Lifecycle functions
backup_system_t* backup_system_create(const backup_config_t* config, gudb* database);
int backup_system_init(backup_system_t* system, logger_t* logger);
void backup_system_destroy(backup_system_t* system);
int backup_system_start_threads(backup_system_t* system);
int backup_system_stop_threads(backup_system_t* system);

// Backup operations
uint64_t backup_system_create_backup(backup_system_t* system,
                                     backup_type_t type,
                                     const char* description);
int backup_system_cancel_backup(backup_system_t* system, uint64_t job_id);
backup_job_t* backup_system_get_job(backup_system_t* system, uint64_t job_id);
int backup_system_list_backups(backup_system_t* system,
                               backup_manifest_t*** manifests,
                               uint32_t* count);

// Recovery operations
uint64_t backup_system_create_recovery(backup_system_t* system,
                                      recovery_type_t type,
                                      uint64_t backup_id,
                                      const char* recovery_path,
                                      time_t target_time);
int backup_system_cancel_recovery(backup_system_t* system, uint64_t recovery_id);
recovery_context_t* backup_system_get_recovery(backup_system_t* system, 
                                               uint64_t recovery_id);

// Backup manifest management
backup_manifest_t* backup_system_create_manifest(backup_system_t* system,
                                                 backup_type_t type,
                                                 const char* description);
int backup_system_save_manifest(backup_system_t* system, backup_manifest_t* manifest);
backup_manifest_t* backup_system_load_manifest(backup_system_t* system, 
                                               uint64_t backup_id);
int backup_system_delete_backup(backup_system_t* system, uint64_t backup_id);

// Utility functions
int backup_system_verify_backup(backup_system_t* system, uint64_t backup_id);
int backup_system_cleanup_old_backups(backup_system_t* system);
const char* backup_type_to_string(backup_type_t type);
const char* backup_status_to_string(backup_status_t status);
const char* recovery_type_to_string(recovery_type_t type);

// Statistics and monitoring
int backup_system_get_stats(backup_system_t* system, backup_system_stats_t* stats);
int backup_system_update_stats(backup_system_t* system);
void backup_system_print_stats(backup_system_t* system);

// File operations
uint64_t calculate_file_checksum(const char* filename);
int compress_file(const char* input_file, const char* output_file, 
                 compression_type_t compression);
int decompress_file(const char* input_file, const char* output_file,
                   compression_type_t compression);
int encrypt_file(const char* input_file, const char* output_file,
                encryption_type_t encryption, const char* key);
int decrypt_file(const char* input_file, const char* output_file,
                encryption_type_t encryption, const char* key);

// Background thread functions
void* backup_system_scheduler_thread(void* arg);
void* backup_system_cleanup_thread(void* arg);
void* backup_job_thread(void* arg);

// Default configuration
static inline backup_config_t backup_system_default_config(void) {
    backup_config_t config = {
        .backup_directory = "./backups",
        .default_type = BACKUP_TYPE_FULL,
        .compression = COMPRESSION_GZIP,
        .encryption = ENCRYPTION_NONE,
        .max_backup_threads = 4,
        .max_backup_size = 10ULL * 1024 * 1024 * 1024, // 10GB
        .retention_days = 30,
        .max_backup_count = 100,
        .enable_checksum = true,
        .enable_compression = true,
        .enable_encryption = false,
        .backup_buffer_size = 1024 * 1024, // 1MB
        .network_timeout_sec = 300
    };
    return config;
}

#ifdef __cplusplus
}
#endif

#endif // GUDB_BACKUP_SYSTEM_H